
//
//  CustomArcProgress.m
//  彩色环形进度条
//
//  Created by MyMac on 15/8/13.
//  Copyright (c) 2015年 MyMac. All rights reserved.
//
#define LINE_WIDTH  20.0
#import <POP.h>
#import "CustomArcProgress.h"
@interface CustomArcProgress()
/**
 *  背景路径图
 */
@property(nonatomic,strong)CAShapeLayer*pressLayer;
/**
 *  渐变路径图
 */
@property(nonatomic,strong)CAShapeLayer*gradientLayer;
/**
 *  裁减后的图层
 */
@property(nonatomic,strong)CAShapeLayer*clipGradientLayer;
@end
/**
 *   思路：首先绘制出路径，利用UIBezierPath绘制路径，，再将路径关联到CAShapeLayer，CAShapeLayer就是要裁减的模版，将绘制路径的方法封装起来-(CAShapeLayer*)backPathWihRect:(CGRect)rect
 
     利用绘制出的路径会一个背景层，可以直接是返回的CAShapeLayer
 
 
     再利用绘制出的路径作为模版画出渐变层，渐变层
 
 
    这里的进度没有是直接修改路径的方法，，，是利用了pop动画自带的一个CAShapeLayer动画，可以改变值，，并且还有回弹效果
 
 
 
 
 */
@implementation CustomArcProgress


-(void)drawRect:(CGRect)rect
{

//    CGContextRef ctf=UIGraphicsGetCurrentContext();
//    UIBezierPath*path=[self backPathWihRect:rect];
//    CGPathRef backPath=path.CGPath;
//
//    CGContextSetRGBStrokeColor(ctf, 0.7, 0.8, 0.8, 0);
//    CGContextAddPath(ctf, backPath);
//
    
    //背景层
    CAShapeLayer*backLayer=[self backPathWihRect:rect];
    backLayer.strokeColor=[UIColor colorWithRed:146/255.0 green:192/255.0 blue:243/255.0 alpha:1].CGColor;
    [self.layer addSublayer:backLayer];
    
    //彩色涂层的裁剪模版与背景层不一样，否则改变进度时，，，背景层的路径值也会改变
    //彩色图层
    self.pressLayer=[self backPathWihRect:rect];
    self.gradientLayer=[self createGradientLayer];
    [self.layer addSublayer:self.gradientLayer];
    self.gradientLayer.mask=self.pressLayer;
    
    
    
    
    
    

}
/**
 *  设置渐变层
 */
-(CAShapeLayer  *)createGradientLayer
{
    CAShapeLayer*layer=[CAShapeLayer layer];
    layer.frame=self.bounds;

//渐变层分为两部分，左边从红到绿  右边从绿到红
    CAGradientLayer*left=[CAGradientLayer layer];
    left.colors=@[(id)[UIColor redColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor yellowColor].CGColor];
    left.frame=CGRectMake(0, 0, self.bounds.size.width/2.0, self.bounds.size.height);
    //从0到1的浮点数
    left.startPoint=CGPointMake(0, 0);
    left.endPoint=CGPointMake(1,1);
    //分段设置渐变色
    left.locations=@[@0.3,@0.6 ,@0.9];
    [layer addSublayer:left];

    
    
    
    CAGradientLayer*right=[CAGradientLayer layer];
    right.colors=@[(id)[UIColor greenColor].CGColor,(id)[UIColor redColor].CGColor,(id)[UIColor blueColor].CGColor];
    right.frame=CGRectMake(self.bounds.size.width/2, 0, self.bounds.size.width/2.0, self.bounds.size.height);
    right.startPoint=CGPointMake(0, 0);
    right.endPoint=CGPointMake(1,1);
    //分段设置渐变色
    right.locations=@[@0.3,@0.6 ,@1.0];
    
    [layer addSublayer:right];
    //裁剪父层，，子层也会跟着裁剪
    return layer;
  



}
-(void)setValue:(CGFloat)value
{
    _value=value;
    [self animationSpringWithValue:_value];
    //可以直接修改strokeEnd的属性值也能达到改变路径的效果
   // self.pressLayer.strokeEnd=_value;

}

-(void)animationSpringWithValue:(CGFloat)value
{
//这个动画是修改CAShapeLayer的strokeEnd的属性值，这个属性值是路径的结束值，，也就是我们不需要修改CAShapeLayer的path属性也能改变路径
    POPSpringAnimation*spring=[POPSpringAnimation animationWithPropertyNamed:kPOPShapeLayerStrokeEnd];
    spring.springBounciness=22.0;
    spring.toValue=@(value);
    spring.removedOnCompletion=NO;
    [self.pressLayer pop_addAnimation:spring forKey:nil];
    




}

/**
 *  画路径
 *
 *  @param rect 大小
 */
-(CAShapeLayer*)backPathWihRect:(CGRect)rect
{

     //绘制弧形路径
    UIBezierPath*backPath=[UIBezierPath  bezierPathWithArcCenter:CGPointMake(rect.size.width/2.0, rect.size.height/2.0) radius:rect.size.width/2.0-LINE_WIDTH/2.0 startAngle:-M_PI_4*5 endAngle:M_PI_4 clockwise:YES];
    CAShapeLayer*backLayer=[CAShapeLayer layer];
    backLayer.frame=self.bounds;
    //backLayer.backgroundColor=[UIColor lightGrayColor].CGColor;
    //边缘线的颜色,要想显示出，即背景必须为非透明
    backLayer.strokeColor=[UIColor blackColor].CGColor;
    //填充颜色，中间的不需要显示，，所以必须为透明色，，，裁剪就是根据非透明留下，，透明的裁去的原理，，所以这里必须为透明色
   backLayer.fillColor=[UIColor clearColor].CGColor;
    //self.backgroundColor=[UIColor whiteColor];
    //线宽。。。设置UIBezierPath的线宽在上下文中有用，在CAShapeLayer无用
    backLayer.lineWidth=LINE_WIDTH;
    backLayer.lineCap=kCALineCapRound;
    CGPathRef CGbackPath=backPath.CGPath;
    
    
    backLayer.path=CGbackPath;
    
    return backLayer;

}
@end
